package it.eng.get.pdfwe.jr;

import it.eng.get.pdfwe.fillers.jr.JRFillerBean;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.jasperreports.engine.JRBand;
import net.sf.jasperreports.engine.JRElement;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRStaticText;
import net.sf.jasperreports.engine.JRTextField;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.base.JRBasePrintPage;
import net.sf.jasperreports.engine.fill.JRTemplatePrintText;

/**
 * @author <div style="width: 100%; height: 2em;
 * background-repeat: repeat-x; 
 * background-image: url(http://www.mysoftworks.net/images/author_back.gif);" >
 * <a style="float: right; font-size: .9em; margin: 1.2em .5em .1em .1em; color: #658A16; color: 658A16; font-family: helvetica; font-weight: bold; text-decoration: none" href="http://www.mysoftworks.net">
 * Antonio Giovannetti for Engineering</a>
 * </div>
 */
public class JasperReportParser {

//	public static String JASPER_REPORT_SESSION_KEY = "JASPER_REPORT_SESSION_KEY";
	public static final Color EDITABLE_FIELD_COLOR = new Color(0,0,1);
	
	static {
		final List<String> toInit = new ArrayList<String>();
		toInit.add("net.sf.jasperreports.engine.JasperFillManager");
		toInit.add("org.htmlcleaner.CleanerProperties");
		toInit.add("org.htmlcleaner.DomSerializer");
		toInit.add("org.htmlcleaner.HtmlCleaner");
		toInit.add("org.htmlcleaner.TagNode");
		toInit.add("org.apache.fop.apps.Fop");
		toInit.add("org.apache.fop.apps.FopFactory");
		toInit.add("org.apache.fop.apps.MimeConstants");	
		toInit.add("javax.xml.parsers.DocumentBuilder");
		toInit.add("javax.xml.parsers.DocumentBuilderFactory");
		toInit.add("javax.xml.transform.Result");
		toInit.add("javax.xml.transform.Source");
		toInit.add("javax.xml.transform.Transformer");
		toInit.add("javax.xml.transform.TransformerFactory");
		toInit.add("javax.xml.transform.dom.DOMSource");
		toInit.add("javax.xml.transform.sax.SAXResult");

		
		Thread t = new Thread() {
			
			public void run() {
				for (String string : toInit) {
					System.out.println("Loading class " + string);
					try {
						Class.forName(string);
					} catch (Exception e) {
						e.printStackTrace();
					}
					
				}
				
			}
		};
		t.start();
		
		
	}
	
	
	
//	private String editingMatchingPatternKey = "@editable:";
	private JasperReport report;
	private JRFillerBean jrfillerbean;
	
//	public void setEditingMatchingPattern(String editingMatchingPattern) {
//		this.editingMatchingPatternKey = editingMatchingPattern;
//	}

	public void setReport(JasperReport report) {
		this.report = report;
	}
	
	public JasperReportParser(JasperReport report,JRFillerBean jrfillerbean) {
		super();
		this.report = report;
		this.jrfillerbean = jrfillerbean;
	}
	
	private boolean matches(JRElement elem) {
		if (elem==null) return false;
//		return key.startsWith(editingMatchingPatternKey);
		return elem.getForecolor().equals(EDITABLE_FIELD_COLOR);
		
	}
	
	private void _addBand(JRBand jRBand,List<JREditableObject> result) {
		if (jRBand==null) return;
		for (JRElement elem : jRBand.getElements()) {
			if (matches(elem)) {
//				if (elem instanceof JRStaticText) {
//					JRStaticText staticTextElem = (JRStaticText) elem;
//					result.add(new JREditableObject(jRBand, elem, elem.getKey().replaceAll(editingMatchingPatternKey, ""), staticTextElem.getText()));
//				}
//				if (elem instanceof JRTextField) {
//					JRTextField jRTextField = (JRTextField) elem;
//					result.add(new JREditableObject(jRBand, elem, elem.getKey().replaceAll(editingMatchingPatternKey, ""), jRTextField.getExpression().getText()));
//				}
				if (elem instanceof JREditableObject) {
					result.add((JREditableObject)elem);
				}
			}
		}
	}

	private void _doUpdateFromKey(JRBand jRBand) {
		if (jRBand==null) return;
		for (JRElement elem : jRBand.getElements()) {
			if (matches(elem)) {
				elem.setForecolor(Color.black);
//				if (elem instanceof JRStaticText) {
//					JRStaticText staticTextElem = (JRStaticText) elem;
//					if (!matches(staticTextElem.getText())) {
//						String text = staticTextElem.getText();
//						staticTextElem.setText(editingMatchingPatternKey + text);
//					}
//				}
//				if (elem instanceof JRTextField) {
//					JRTextField jRTextField = (JRTextField) elem;
//					jRTextField.setForecolor(EDITABLE_FIELD_COLOR);
//					System.out.println("getText:" + jRTextField.getExpression().getText());
//				}
			}
		}	
	}

	
	private boolean _doUpdateBand(JRBand jRBand,String key,String value) {
		if (jRBand==null) return false;
		for (JRElement elem : jRBand.getElements()) {
			if (key.equals(elem.getKey())) {
				if (elem instanceof JRStaticText) {
					JRStaticText staticTextElem = (JRStaticText) elem;
					staticTextElem.setText(value);
					return true;
				}
				if (elem instanceof JRTextField) {
					JRTextField jRTextField = (JRTextField) elem;
				}
			}
		}	
		return false;
	}

	
	private void _doUpdate(String key,String value) {
		_doUpdateBand(report.getDetail(),key,value);
		_doUpdateBand(report.getTitle(),key,value);
		_doUpdateBand(report.getBackground(),key,value);
		_doUpdateBand(report.getColumnFooter(),key,value);
		_doUpdateBand(report.getColumnHeader(),key,value);
		_doUpdateBand(report.getLastPageFooter(),key,value);
		_doUpdateBand(report.getNoData(),key,value);
		_doUpdateBand(report.getPageFooter(),key,value);
		_doUpdateBand(report.getPageHeader(),key,value);
		_doUpdateBand(report.getSummary(),key,value);
	}
	
	public List<JREditableObject> getEditables() {
		if (report==null) return null;
		List<JREditableObject> result = new ArrayList<JREditableObject>();
			JRBand detail = report.getDetail();
			_addBand(detail,result);
			JRBand title = report.getTitle();
			_addBand(title,result);
		return result;
	
	}
	
	
	public void setEditables(HttpServletRequest request) {
		Enumeration enumer = request.getParameterNames();
		while(enumer.hasMoreElements()) {
			Object elem = enumer.nextElement();
			if (elem instanceof String) {
				String key = (String) elem;
//				if (matches(key)) {
//					String value=request.getParameter(key);
//					System.out.println("Updating " + key + " with value:" + value );
//					_doUpdate(key,value);
//					
//				}
			}
		}
	}
	
	
	public void postProcessTextUpdater(JasperPrint print,String oldVal,String newVal) {
		if (print==null) return;
		if (oldVal==null) return;
		List lpages = print.getPages();
		for (Object opage : lpages) {
			if (opage instanceof JRBasePrintPage) {
				JRBasePrintPage page = (JRBasePrintPage) opage;
				List list = page.getElements();
				for (Object object : list) {
					if (object instanceof JRTemplatePrintText) {
						JRTemplatePrintText pt = (JRTemplatePrintText) object;
						if (oldVal.equals(pt.getText())) pt.setText(newVal);
					}
				}
			}
		}
		
	}
	
	private void copyEditablesFromKeyToText() {
		_doUpdateFromKey(report.getDetail());
		_doUpdateFromKey(report.getTitle());
		_doUpdateFromKey(report.getBackground());
		_doUpdateFromKey(report.getColumnFooter());
		_doUpdateFromKey(report.getColumnHeader());
		_doUpdateFromKey(report.getLastPageFooter());
		_doUpdateFromKey(report.getNoData());
		_doUpdateFromKey(report.getPageFooter());
		_doUpdateFromKey(report.getPageHeader());
		_doUpdateFromKey(report.getSummary());		
	}
	
	public JasperPrint getJasperPrint() throws JRException {
		return JasperFillManager.fillReport(report, jrfillerbean.getParams(), jrfillerbean.getJrDataSource());
	}

	public JasperPrintWebEditor getJasperPrintWebEditor() throws JRException {
//		copyEditablesFromKeyToText();
		return new JasperPrintWebEditor(getJasperPrint());
	}

	
	
}
